import React, { useState, useRef, useEffect } from 'react';
import { Button } from 'antd'
import './jiequ.scss';


const App = () => {
    // 绘制框dom
    const myRef = useRef(null);
    const [src, setSrc] = useState('');


    // canvasDom
    const canvasRef = useRef(null);

    // 覆盖框的宽
    const [catwidth, setCatwidth] = useState(0);
    // 覆盖框的高
    const [catheight, setCatheight] = useState(0);
    // 截取框的宽高
    const [jqwh, setjqwh] = useState(85);
    // 截取框位置
    const [position, setPosition] = useState({ top: 0, left: 0 });
    // 是否移动中
    const [dragging, setDragging] = useState(false);
    // 四角移动中
    const [jiao, setJiao] = useState(false);
    // 鼠标位置
    const initialMousePos = useRef({ x: 0, y: 0 });
    // 实时span
    const spanshishi = useRef(null);

    const handleMouseDown = (e, bol, id) => {
        // 防止冒泡
        e.stopPropagation();
        // 防止选中内容
        e.preventDefault();
        // 判断是否是移动还是拉伸
        bol ? setDragging(true) : setJiao(true);
        // 记录鼠标按下的坐标
        initialMousePos.current = { x: e.clientX, y: e.clientY };

        // 记录span的初始位置 实时拖动
        spanshishi.current = id;
        // 重置定位

        if (jqwh == 1) {
            // 获取父元素
            const parentElement = e.target.parentElement;
            // 自身位置信息
            const childRect = e.target.getBoundingClientRect();
            // 父元素位置信息
            const parentRect = parentElement.getBoundingClientRect();
            // 修改定位
            setPosition({ top: e.clientY - childRect.top, left: e.clientX - parentRect.left });
        }
    };

    const handleMouseUp = () => {
        setDragging(false);
        setJiao(false);
    };
    const handleMouseMove = (e) => {
        if (dragging && !jiao) {
            // 鼠标X移动的距离
            const deltaX = e.clientX - initialMousePos.current.x;
            // 鼠标Y移动的距离
            const deltaY = e.clientY - initialMousePos.current.y;
            // 改变截取框位置
            let newTop = position.top + deltaY;
            let newLeft = position.left + deltaX;

            if (newTop > catheight - jqwh) {
                newTop = catheight - jqwh
            }
            if (newLeft > catwidth - jqwh) {
                newLeft = catwidth - jqwh
            }

            if (newTop / 2 < 0) {
                newTop = 0
            }
            if (newLeft / 2 < 0) {
                newLeft = 0
            }
            setPosition({ top: newTop, left: newLeft });
        }
        // console.log(111)


        if (jiao) {
            let deltaX = e.clientX - initialMousePos.current.x;
            let deltaY = e.clientY - initialMousePos.current.y;
            switch (spanshishi.current) {
                // prev.top   prev.left为实时的      position不是实时的 ！！！

                case 'left-top':
                    // 获取最新宽高
                    let newnum4 = jqwh - deltaX;
                    if (newnum4 < 1) {
                        newnum4 = 1;
                    }
                    setPosition((prev) => {
                        // 左上角 距离左 上都要大于0才可以设置大小
                        if (prev.top > 0 && prev.left > 0) {
                            setjqwh(newnum4);
                        }
                        //    新top  小于0判断   |  小于0时再判断prev.left > 0说明是触碰顶部线(0) 否则触碰左线(默认prev.top) | prev.left > 0和宽高大于0  设置值 否则默认值prev.top |     顶部大于0        左边大于等于0      宽度大于0      |      左侧都满足 设置值 设置时判断是否小于0                    | 默认          
                        return { ...prev, top: position.top + deltaX < 0 ? prev.left > 0 ? 0 : prev.top : prev.left > 0 && newnum4 > 0 ? position.top + deltaX : prev.top, left: prev.top > 0 && prev.left >= 0 && newnum4 > 0 ? position.left + deltaX < 0 ? 0 : position.left + deltaX : prev.left };
                    });
                    break;
                case 'left-bottom':

                    let newnum3 = jqwh - deltaX;

                    if (newnum3 < 1) {
                        newnum3 = 1;
                    }
                    setPosition((prev) => {
                        // 左下角 距离左侧大于0才可以设置大小
                        if (prev.left > 0) {
                            setjqwh(newnum3);
                        }
                        //                     左侧大于0      宽度大于0      |     顶部距离top加上自身的高不能大于所在框的高   | 满足左侧  设置值                                     |  默认              
                        return { ...prev, left: prev.left >= 0 && newnum3 > 0 && prev.top + newnum3 < catheight ? position.left + deltaX < 0 ? 0 : position.left + deltaX : prev.left };
                    });
                    break;
                case 'right-top':

                    let newnum2 = jqwh + deltaX;
                    if (newnum2 < 1) {
                        newnum2 = 1;
                    }
                    setPosition((prev) => {
                        // console.log(prev, '22222>')
                        // 右上角 距离顶部大于0   距离左侧加上自身宽度小于所在框的宽  才可以设置大小
                        if (prev.top > 0 && prev.left + newnum2 < catwidth) {
                            setjqwh(newnum2);
                        }
                        //               是否小于0判断  小于0状态 prev.left + newnum2 < catwidth为顶部线(0) 否则为右侧线(prev.top) | 距离左侧加上自身宽度小于所在框的宽   宽高大于0  | 满足左侧  设置值          |  默认
                        return { ...prev, top: position.top - deltaX < 0 ? prev.left + newnum2 < catwidth ? 0 : prev.top : position.left + newnum2 < catwidth && newnum2 > 0 ? position.top - deltaX : prev.top };
                    });
                    break;
                case 'right-bottom':

                    let newnum = jqwh + deltaX;


                    if (newnum < 1) {
                        newnum = 1;
                    }

                    // if (deltaX < 0 && Math.abs(deltaX) > jqwh) {
                    //     console.log('向左')
                    // }
                    // if (deltaY < 0 && Math.abs(deltaY) > jqwh) {
                    //     console.log('向上')
                    // }

                    // 修改大小
                    setjqwh(newnum);
                    break;
                default:
                    break;
            }
        }
    };

    useEffect(() => {
        // 限制拖拽截取框大小 图片上传后
        if (jqwh + position.left > catwidth && src) {
            setjqwh(catwidth - position.left < 1 ? 1 : catwidth - position.left)
        } else if (jqwh + position.top > catheight && src) {
            setjqwh(catheight - position.top < 1 ? 1 : catheight - position.top)
        }

    }, [jqwh])

    useEffect(() => {
        // 拖动截取框
        if (dragging) {
            window.addEventListener('mousemove', handleMouseMove);
        } else {
            window.removeEventListener('mousemove', handleMouseMove);
        }

        return () => {
            window.removeEventListener('mousemove', handleMouseMove);
        };
    }, [dragging])
    useEffect(() => {
        // 拖动截取框大小
        if (jiao) {
            window.addEventListener('mousemove', handleMouseMove);
        } else {
            window.removeEventListener('mousemove', handleMouseMove);
        }

        return () => {
            window.removeEventListener('mousemove', handleMouseMove);
        };
    }, [jiao])

    useEffect(() => {
        // 实时绘制canvas
        drawCanvas()
    }, [src, jqwh, position])

    // 处理文件上传
    const handleFileChange = (e) => {
        const file = e.target.files[0];
        if (file) {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => {
                const img = new Image();
                img.src = reader.result;

                img.onload = () => {
                    const containerWidth = 300;
                    const containerHeight = 300;
                    // 等比例
                    const imgRatio = img.width / img.height;
                    const containerRatio = containerWidth / containerHeight;

                    let displayWidth, displayHeight;

                    if (imgRatio > containerRatio) {
                        displayWidth = containerWidth;
                        displayHeight = containerWidth / imgRatio;
                    } else {
                        displayHeight = containerHeight;
                        displayWidth = containerHeight * imgRatio;
                    }
                    // 设置SRC
                    setSrc(reader.result);
                    // 设置覆盖框宽高
                    setCatwidth(displayWidth);
                    setCatheight(displayHeight);
                    // 重置截取框位置
                    setPosition({ left: 0, top: 0 });
                    // 重置截取框大小
                    setjqwh(85);
                };
            };
        }
    };

    // 绘制 Canvas
    const drawCanvas = () => {
        if (myRef.current && src) {
            const img = new Image();
            img.src = src;
            img.onload = () => {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');

                // 获取图像实际尺寸
                const imgWidth = img.naturalWidth;
                const imgHeight = img.naturalHeight;

                // 设置 Canvas 尺寸
                canvas.width = 85;
                canvas.height = 85;

                // 计算源区域的位置和尺寸
                const sourceX = position.left * (imgWidth / catwidth); // 调整为图像的实际坐标
                const sourceY = position.top * (imgHeight / catheight); // 调整为图像的实际坐标
                const sourceWidth = jqwh * (imgWidth / catwidth); // 调整为图像的实际宽度
                const sourceHeight = jqwh * (imgHeight / catheight); // 调整为图像的实际高度

                // 绘制指定区域到 Canvas
                ctx.drawImage(
                    img,
                    sourceX, sourceY, sourceWidth, sourceHeight,
                    0, 0, canvas.width, canvas.height
                );

                // 将 Canvas 添加到 myRef 当前元素中
                const refElement = myRef.current;
                canvasRef.current = canvas
                refElement.innerHTML = ''; // 清空当前内容
                refElement.appendChild(canvas);
            };
        }
    };
    const handleCut = () => {
        // 获取canvas
        const canvas = canvasRef.current;
        // 转换成blob
        canvas.toBlob((blob) => {
            if (blob) {
                // 创建 File 对象
                const file = new File([blob], 'canvas-image.png', { type: blob.type });
                console.log(file, 'file')

                // file文件上传到服务器
                const formData = new FormData();
                formData.append('file', file);
            }
        }, 'image/png');
    }



    // 样式集合
    const imgbox = {
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        position: 'relative',
        backgroundColor: src ? '#000' : 'transparent',
    }
    const whtbox1 = {
        width: `${jqwh}px`,
        height: `${jqwh}px`,
        position: 'absolute',
        top: position.top,
        left: position.left,
        background: 'transparent',
        border: '1px solid #fff',
        cursor: 'move',
        backgroundImage: `url(${src})`,
        backgroundRepeat: 'no-repeat',
        backgroundPosition: `-${position.left}px -${position.top}px`,
        backgroundSize: `${catwidth}px ${catheight}px`,
        zIndex: 10,
        display: jqwh == 1 ? 'none' : 'block',
    };
    const whtbox2 = {
        width: `${jqwh}px`,
        height: `${jqwh}px`,
        position: 'absolute',
        top: position.top,
        left: position.left,
        transform: `translate(${0}, ${0})`,
        background: 'transparent',
        // border: '1px solid #fff',
        cursor: 'move',
        zIndex: 1,
    };
    const spans = {
        border: '1px solid #fff',
        position: 'absolute',
        width: '10px',
        height: '10px',
        display: jqwh == 1 ? 'none' : 'block',
        transition: '.1s',
    }
    // 全局可抬起
    window.onmouseup = handleMouseUp

    return (
        <>
            <div className='box' onMouseUp={handleMouseUp}>
                <div style={imgbox}>
                    <img src={src} style={{ width: '300px', height: '300px', objectFit: 'contain', display: src ? 'block' : 'none' }} />
                    <div style={{ width: catwidth, height: catheight, position: 'absolute', background: 'rgba(0, 0, 0, 0.5)', cursor: jqwh == 1 ? 'crosshair' : 'auto' }} onMouseDown={jqwh == 1 ? (e) => handleMouseDown(e, false, 'right-bottom') : null} onMouseUp={handleMouseUp}>
                        <div style={whtbox1} onMouseDown={(e) => handleMouseDown(e, true)} onMouseUp={handleMouseUp}></div>
                        <div style={whtbox2}>
                            <span onMouseDown={(e) => handleMouseDown(e, false, 'left-top')} onMouseUp={handleMouseUp} style={{ ...spans, top: '-11px', left: '-11px', cursor: 'nw-resize' }}></span>
                            <span onMouseDown={(e) => handleMouseDown(e, false, 'left-bottom')} onMouseUp={handleMouseUp} style={{ ...spans, bottom: '-11px', left: '-11px', cursor: 'sw-resize' }}></span>
                            <span onMouseDown={(e) => handleMouseDown(e, false, 'right-top')} onMouseUp={handleMouseUp} style={{ ...spans, top: '-11px', right: '-11px', cursor: 'sw-resize' }}></span>
                            <span onMouseDown={(e) => handleMouseDown(e, false, 'right-bottom')} onMouseUp={handleMouseUp} style={{ ...spans, bottom: '-11px', right: '-11px', cursor: 'nw-resize' }}></span>
                        </div>
                    </div>
                </div>
                <div ref={myRef} style={{ width: '85px', height: '85px', display: 'flex', justifyContent: 'center', alignItems: 'center', margin: '100px', borderRadius: '50%', overflow: 'hidden' }}>
                    {/* Canvas 会被绘制到这个 div 中 */}
                </div>
            </div>
            <br />
            <input type="file" onChange={handleFileChange} />
            <Button type='primary' onClick={handleCut}>上传</Button>
        </>
    );
};

export default App;